package org.yak.core.nosql;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.bson.Document;
import org.bson.conversions.Bson;
import org.yak.core.nosql.entity.MongoSortField;
import org.yak.core.utils.ConfigUtils;
import org.yak.core.utils.JsonUtils;

import com.mongodb.Block;
import com.mongodb.MongoClient;
import com.mongodb.client.FindIterable;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoCursor;
import com.mongodb.client.MongoDatabase;
import com.mongodb.client.model.Filters;

public class MongoDBConfig {
	private static MongoClient mongoClient;
	
	static {
		String server_ip = ConfigUtils.getConfigValue("mongodb_server_ip");
		int server_port = Integer.parseInt(ConfigUtils.getConfigValue("mongodb_server_port"));
		mongoClient = new MongoClient(server_ip, server_port);
	}

	/*public MongoDBConfig(String host,int port){
		mongoClient = new MongoClient(host, port);
	}

	public MongoDBConfig(String host,int port,String db){
		mongoClient = new MongoClient(host, port);
		mongoClient.getDatabase(db);
		System.out.println("Connect to database successfully");
	}*/
	
	/**
	 * 获取数据库
	 * @param dbName
	 * @return
	 */
	public static MongoDatabase getDB(String dbName) {
		return mongoClient.getDatabase(dbName);
	}
	/**
	 * 删除数据库
	 * @param dbName
	 * @return
	 */
	public static boolean dropDB(String dbName) {
		mongoClient.dropDatabase(dbName);
		return true;
	}
	
	/**
	 * 获取指定数据库的指定表
	 * @param dbName
	 * @param connectionName
	 * @return
	 */
	public static MongoCollection<Document> getDbConnection(String dbName,String connectionName) {
		return mongoClient.getDatabase(dbName).getCollection(connectionName);
	}
	
	/**
	 * 清空
	 * @param connectionName
	 * @return
	 */
	public static boolean dropConnection(String dbName,String connectionName) {
		mongoClient.getDatabase(dbName).getCollection(connectionName).drop();
		return true;
	}
	
	/**
	 * 插入
	 * @param dbName 数据库名称
	 * @param connectionName 结合表名
	 * @param valueMap 行记录
	 * @return
	 */
	public static boolean insert(String dbName,String connectionName,Map<String,Object> valueMap){
		MongoCollection<Document> collection = mongoClient.getDatabase(dbName).getCollection(connectionName);
		Document document = new Document(valueMap);
		collection.insertOne(document);
		return true;
	}
	
	/**
	 * 批量插入
	 * @param dbName
	 * @param connectionName
	 * @param valueMap
	 * @return
	 */
	public static boolean insert(String dbName,String connectionName,List<Map<String,Object>> valueMap){
		MongoCollection<Document> collection = mongoClient.getDatabase(dbName).getCollection(connectionName);
		List<Document> list = new ArrayList<Document>();
		for(Map<String,Object> map : valueMap) {
			list.add(new Document(map));
		}
		collection.insertMany(list);
		return true;
	}
	
	/**
	 * 多重条件更新数据
	 * 更新记录
	 * @param dbName 数据库
	 * @param connectionName 表
	 * @param queryFilter 查询条件
	 * @param updateValueMap 更新字段和内容
	 * @return
	 */
	public static boolean update(String dbName,String connectionName,Bson queryFilter,Map<String,Object> updateValueMap) {
		MongoCollection<Document> collection = mongoClient.getDatabase(dbName).getCollection(connectionName);
		Document update = new Document();
		update.put("$set", updateValueMap);
		collection.updateMany(queryFilter, update);
		return true;
	}
	
	/**
	 * 更新记录
	 * @param dbName 数据库
	 * @param connectionName 表
	 * @param queryFilter 查询条件
	 * @param updateValueMap 更新字段和内容
	 * @return
	 */
	public static boolean update(String dbName,String connectionName,Map<String,Object> queryFilter,Map<String,Object> updateValueMap) {
		MongoCollection<Document> collection = mongoClient.getDatabase(dbName).getCollection(connectionName);
		Document query = new Document(queryFilter);
		Document update = new Document();
		update.put("$set", updateValueMap);
		collection.updateMany(query, update);
		return true;
	}
	
	/**
	 * 多条件组合删除数据
	 * @param dbName
	 * @param connectionName
	 * @param queryFilter
	 * @return
	 */
	public static boolean delete(String dbName,String connectionName,Bson queryFilter) {
		//七天前的数据
		/*Bson createTimeBson = Filters.lte("creatTime",  DateTimeUtils.addSomeDay(new Date(), -7));
		//in 条件
		Bson parentPushTypeBson = Filters.in("parentPushType", "03","04");
		//用and链接
		Bson bson = Filters.and(createTimeBson, parentPushTypeBson);
		collection.deleteMany(bson)
		*/
		MongoCollection<Document> collection = mongoClient.getDatabase(dbName).getCollection(connectionName);
		collection.deleteMany(queryFilter);
		return true;
	}
	
	/**
	 * 删除
	 * 更新记录
	 * @param dbName 数据库
	 * @param connectionName 表
	 * @param queryFilter 查询条件
	 * @return
	 */
	public static boolean delete(String dbName,String connectionName,Map<String,Object> queryFilter) {
		MongoCollection<Document> collection = mongoClient.getDatabase(dbName).getCollection(connectionName);
		Document query = new Document(queryFilter);
		collection.deleteMany(query);
		return true;
	}
	
	/**
	 * 清空指定表所有数据
	 * @param dbName 数据库
	 * @param connectionName 表
	 * @return
	 */
	public static boolean deleteAll(String dbName,String connectionName) {
		MongoCollection<Document> collection = mongoClient.getDatabase(dbName).getCollection(connectionName);
		collection.drop();
		return true;
	}
	
	/**
	 * 查询指定字段内容，结果返回list
	 * @param dbName
	 * @param connectionName
	 * @param fieldName
	 * @param queryFilter
	 * @return
	 */
	public static List<Object> querList(String dbName,String connectionName,Map<String,Object> queryFilter,String fieldName) {
		List<Object> result = new ArrayList<Object>();
		MongoCollection<Document> collection = mongoClient.getDatabase(dbName).getCollection(connectionName);
		FindIterable<Document> documentMap = null;
		if(queryFilter == null) {
			documentMap =  collection.find();
		}else {
			Document query = new Document(queryFilter);
			documentMap = collection.find(query);
		}
		documentMap.forEach(new Block<Document>() {
				public void apply(Document _doc) {
					if(_doc.containsKey(fieldName)) {
						result.add(_doc.get(fieldName));
					}
				}
			});
		return result;
	}
	
	/**
	 * 查询指定字段内容，结果返回list
	 * @param dbName
	 * @param connectionName
	 * @param fieldName
	 * @param queryFilter
	 * @return
	 */
	public static List<Object[]> querList(String dbName,String connectionName,Map<String,Object> queryFilter,String[] fieldName) {
		List<Object[]> result = new ArrayList<Object[]>();
		MongoCollection<Document> collection = mongoClient.getDatabase(dbName).getCollection(connectionName);
		FindIterable<Document> documentMap = null;
		if(queryFilter == null) {
			documentMap =  collection.find();
		}else {
			Document query = new Document(queryFilter);
			documentMap = collection.find(query);
		}
		documentMap.forEach(new Block<Document>() {
				public void apply(Document _doc) {
					List<Object> valuelist = new ArrayList<Object>();
					for(String field_name : fieldName) {
						valuelist.add(_doc.get(field_name));
					}
					result.add(valuelist.toArray());
					
				}
			});
		return result;
	}
	
	/**
	 * 查询指定字段内容，结果返回list
	 * @param dbName
	 * @param connectionName
	 * @param fieldName
	 * @param queryFilter
	 * @param sortFieldList
	 * @return
	 */
	public static List<Object> querList(String dbName,String connectionName,Map<String,Object> queryFilter,String fieldName,List<MongoSortField> sortFieldList) {
		List<Object> result = new ArrayList<Object>();
		MongoCollection<Document> collection = mongoClient.getDatabase(dbName).getCollection(connectionName);
		FindIterable<Document> documentMap = null;
		if(queryFilter == null) {
			documentMap =  collection.find();
		}else {
			Document query = new Document(queryFilter);
			documentMap = collection.find(query);
		}
		Document sortParam = new Document();
		for(MongoSortField sortField : sortFieldList) {
			Map<String,Object> param = new HashMap<String,Object>();
			param.put(sortField.getOrder_by_field(), sortField.getOrder_by_type());
			sortParam.putAll(param);
			
		}
		documentMap.sort(sortParam);
		documentMap.forEach(new Block<Document>() {
				public void apply(Document _doc) {
					if(_doc.containsKey(fieldName)) {
						result.add(_doc.get(fieldName));
					}
				}
			});
		return result;
	}
	
	/**
	 * 查询结果,map集合key为大写
	 * @param dbName
	 * @param connectionName
	 * @param queryFilter
	 * @return
	 */
	public static List<Map<String,Object>> queryMapList(String dbName,String connectionName,Map<String,Object> queryFilter) {
		List<Map<String,Object>> result = new ArrayList<Map<String,Object>>();
		MongoCollection<Document> collection = mongoClient.getDatabase(dbName).getCollection(connectionName);
		FindIterable<Document> documentMap = null;
		if(queryFilter == null) {
			documentMap =  collection.find();
		}else {
			Document query = new Document(queryFilter);
			documentMap = collection.find(query);
		}
		documentMap.forEach(new Block<Document>() {
				public void apply(Document _doc) {
					System.out.println(_doc.toJson());
					result.add(JsonUtils.toMap(_doc.toJson()));
				}
			});
		return result;
	}
	
	/**
	 * 查询结果,map集合key为大写
	 * @param dbName 数据库
	 * @param connectionName 表
	 * @param queryFilter 查询条件
	 * @param sortFieldList 排序字段
	 * @return
	 */
	public static List<Map<String,Object>> queryMapList(String dbName,String connectionName,Bson queryFilter,List<MongoSortField> sortFieldList) {
		List<Map<String,Object>> result = new ArrayList<Map<String,Object>>();
		MongoCollection<Document> collection = mongoClient.getDatabase(dbName).getCollection(connectionName);
		FindIterable<Document> documentMap = null;
		if(queryFilter == null) {
			documentMap =  collection.find();
		}else {
			documentMap = collection.find(queryFilter);
		}
		Document sortParam = new Document();
		for(MongoSortField sortField : sortFieldList) {
			Map<String,Object> param = new HashMap<String,Object>();
			param.put(sortField.getOrder_by_field(), sortField.getOrder_by_type());
			sortParam.putAll(param);
			
		}
		documentMap.sort(sortParam);
		documentMap.forEach(new Block<Document>() {
				public void apply(Document _doc) {
					System.out.println(_doc.toJson());
					result.add(JsonUtils.toMap(_doc.toJson()));
				}
			});
		return result;
	}
	
	/**
	 * 查询结果,map集合key为大写
	 * @param dbName
	 * @param connectionName
	 * @param queryFilter
	 * @return
	 */
	public static List<Map<String,Object>> queryMapList(String dbName,String connectionName,Bson queryFilter) {
		List<Map<String,Object>> result = new ArrayList<Map<String,Object>>();
		MongoCollection<Document> collection = mongoClient.getDatabase(dbName).getCollection(connectionName);
		FindIterable<Document> documentMap = null;
		if(queryFilter == null) {
			documentMap =  collection.find();
		}else {
			documentMap = collection.find(queryFilter);
		}
		documentMap.forEach(new Block<Document>() {
				public void apply(Document _doc) {
					result.add(JsonUtils.toMap(_doc.toJson()));
				}
			});
		return result;
	}
	
	/**
	 * 查询结果集，结果返回实体对象
	 * @param dbName
	 * @param connectionName
	 * @param queryFilter
	 * @param clazz
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static <T> List<T> queryEntityList(String dbName,String connectionName,Map<String,Object> queryFilter,Class<?> clazz) {
		List<T> result = new ArrayList<T>();
		MongoCollection<Document> collection = mongoClient.getDatabase(dbName).getCollection(connectionName);
		FindIterable<Document> documentMap = null;
		if(queryFilter == null) {
			documentMap =  collection.find();
		}else {
			Document _doc = new Document(queryFilter);
			documentMap = collection.find(_doc);
		}
		
		documentMap.forEach(new Block<Document>() {
				public void apply(Document _doc) {
					result.add((T)JsonUtils.toClass(_doc.toJson(), clazz));
				}
			});
		return result;
	}
	
	/**
	 * 查询结果集，结果返回实体对象
	 * @param dbName
	 * @param connectionName
	 * @param queryFilter
	 * @param clazz
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static <T> List<T> queryEntityList(String dbName,String connectionName,Map<String,Object> queryFilter,Class<?> clazz,List<MongoSortField> sortFieldList) {
		List<T> result = new ArrayList<T>();
		MongoCollection<Document> collection = mongoClient.getDatabase(dbName).getCollection(connectionName);
		FindIterable<Document> documentMap = null;
		if(queryFilter == null) {
			documentMap =  collection.find();
		}else {
			Document _doc = new Document(queryFilter);
			documentMap = collection.find(_doc);
		}
		Document sortParam = new Document();
		for(MongoSortField sortField : sortFieldList) {
			Map<String,Object> param = new HashMap<String,Object>();
			param.put(sortField.getOrder_by_field(), sortField.getOrder_by_type());
			sortParam.putAll(param);
			
		}
		documentMap.sort(sortParam);
		MongoCursor<Document> iters = documentMap.iterator();
		while(iters.hasNext()) {
			Document _doc = iters.next();
			result.add((T) JsonUtils.toClass(_doc.toJson(), clazz));
		}
		/*documentMap.forEach(new Block<Document>() {
				public void apply(Document _doc) {
					result.add((T)JsonUtils.toClass(_doc.toJson(), clazz));
				}
			});*/
		return result;
	}
	
	/**
	 * 查询结果集，结果返回实体对象
	 * @param dbName
	 * @param connectionName
	 * @param queryFilter
	 * @param clazz
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static <T> List<T> queryEntityList(String dbName,String connectionName,Bson queryFilter,Class<?> clazz) {
		List<T> result = new ArrayList<T>();
		MongoCollection<Document> collection = mongoClient.getDatabase(dbName).getCollection(connectionName);
		FindIterable<Document> documentMap = null;
		if(queryFilter == null) {
			documentMap =  collection.find();
		}else {
			documentMap = collection.find(queryFilter);
		}
		
		documentMap.forEach(new Block<Document>() {
				public void apply(Document _doc) {
					result.add((T) JsonUtils.toClass(_doc.toJson(), clazz));
				}
			});
		return result;
	}
	
	/**
	 * 
	 * 查询结果集，结果返回实体对象，可以按照字段排序
	 * @param dbName
	 * @param connectionName
	 * @param queryFilter
	 * @param clazz
	 * @param sortFieldList 排序字段
	 * @return
	 */
	public static List<Object> queryEntityList(String dbName,String connectionName,Bson queryFilter,Class<?> clazz,List<MongoSortField> sortFieldList) {
		List<Object> result = new ArrayList<Object>();
		MongoCollection<Document> collection = mongoClient.getDatabase(dbName).getCollection(connectionName);
		FindIterable<Document> documentMap = null;
		if(queryFilter == null) {
			documentMap =  collection.find();
		}else {
			documentMap = collection.find(queryFilter);
		}
		Document sortParam = new Document();
		for(MongoSortField sortField : sortFieldList) {
			Map<String,Object> param = new HashMap<String,Object>();
			param.put(sortField.getOrder_by_field(), sortField.getOrder_by_type());
			sortParam.putAll(param);
			
		}
		documentMap.sort(sortParam);
		documentMap.forEach(new Block<Document>() {
				public void apply(Document _doc) {
					result.add(JsonUtils.toClass(_doc.toJson(), clazz));
				}
			});
		return result;
	}
	
	

	public static void main(String args[]) {
		//MongoDBConfig config = new MongoDBConfig("121.196.226.121",27017,"bkfm");
		//新增
		Map<String,Object> insertMap = new HashMap<String,Object>();
		insertMap.put("user_no", "system");
		insertMap.put("user_name", "system");
		insertMap.put("user_pwd", "123456");
		//config.insert("bkfm", "student",insertMap);
		
		//修改
		Map<String,Object> filterMap = new HashMap<String,Object>();
		filterMap.put("user_no", "system123");
		Map<String,Object> updateValueMap = new HashMap<String,Object>();
		updateValueMap.put("user_no", "system");
		updateValueMap.put("user_name", "system12333");
		updateValueMap.put("user_pwd", "123456445");
		//config.update("bkfm", "student", filterMap, updateValueMap);
		
		//删除
		Map<String,Object> delFilterMap = new HashMap<String,Object>();
		delFilterMap.put("user_no", "system");
		//config.delete("bkfm", "student", delFilterMap);
		
		Map<String,Object> queryFilterMap = new HashMap<String,Object>();
		queryFilterMap.put("obj_path", "ROOT/XTGLPT/JCSJGL/YHXX/BLK_BASE_USERS");
		List<Object> list = querList("bkfm", "blk_table_metadata",queryFilterMap,"tablemetadata_id");
		List<MongoSortField> sortFieldList = new ArrayList<MongoSortField>();
		MongoSortField fi = new MongoSortField();
		fi.setOrder_by_field("is_primary_key");
		fi.setOrder_by_type(MongoSortField.ASC);
		sortFieldList.add(fi);
		MongoSortField fi2 = new MongoSortField();
		fi2.setOrder_by_field("order_by");
		fi2.setOrder_by_type(MongoSortField.ASC);
		sortFieldList.add(fi2);
		List<Map<String,Object>> result = queryMapList("bkfm", "blk_table_metadata", Filters.in("father_tablemetadata_id", list),sortFieldList);
		System.out.println(result.size());
		/*try {
			// 连接到 mongodb 服务
			MongoClient mongoClient = new MongoClient("localhost", 27017);

			// 连接到数据库
			MongoDatabase mongoDatabase = mongoClient.getDatabase("fpds");
			System.out.println("Connect to database successfully");

			MongoCollection<Document> collection = mongoDatabase.getCollection("student");

			System.out.println("集合 student 选择成功:"+collection.count());
		} catch (Exception e) {
			System.err.println(e.getClass().getName() + ": " + e.getMessage());
		}*/
	}
}
